﻿package {
	
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	
	public class ICharacter extends Character{
		
		//Jump variables
		protected var _jumpheight:int;
		protected var _fallspeed:int;
		protected var _myJump:int;
		protected var _falling:Boolean;
		
		//Keys
		protected var _leftkey:int = 37;
		protected var _rightkey:int = 39;
		protected var _downkey:int = 40;
		protected var _upkey:int = 38;
		protected var _special_1:int = 32;
		protected var _special_2:int;
		protected var _special_3:int;
		protected var _special_4:int;
		
		protected var _leftIsDown:Boolean = false;
		protected var _rightIsDown:Boolean = false;
		protected var _downIsDown:Boolean = false;
		protected var _upIsDown:Boolean = false;
		protected var _special1IsDown:Boolean = false;
		protected var _special2IsDown:Boolean = false;
		protected var _special3IsDown:Boolean = false;
		protected var _special4IsDown:Boolean = false;
		
		//Actions for keys		
		protected var _left_keydown_action:Function = function(){
																this.addEventListener("enterFrame", moveLeft); 
																this.removeEventListener("enterFrame", moveRight);
													};
													
		protected var _right_keydown_action:Function = function(){
																this.addEventListener("enterFrame", moveRight);
																this.removeEventListener("enterFrame", moveLeft)
													};
													
		protected var _down_keydown_action:Function = function(){
																this.addEventListener("enterFrame", moveDown);
																this.removeEventListener("enterFrame", moveUp);
													};

		protected var _up_keydown_action:Function = function(){
																this.addEventListener("enterFrame", moveUp); 
																this.removeEventListener("enterFrame", moveDown);
													};
		
		protected var _left_keyup_action:Function = function(){ 
																this.removeEventListener("enterFrame", moveLeft); 
																if (_rightIsDown) this.addEventListener("enterFrame", moveRight);
																else gotoAndStop("standing");
													};
													
		protected var _right_keyup_action:Function = function(){ 
																this.removeEventListener("enterFrame", moveRight);
																if (_leftIsDown) this.addEventListener("enterFrame", moveLeft);				
																else gotoAndStop("standing");
													};
													
		protected var _down_keyup_action:Function = function(){};
													
		protected var _up_keyup_action:Function = function(){		
																this.removeEventListener("enterFrame", moveUp);
																this.addEventListener("enterFrame", moveDown);
													};
													
		protected var _special_1_keydown_action:Function = function () {};
		protected var _special_1_keyup_action:Function  = function() {};
		
		protected var _special_2_keydown_action:Function = function () {};
		protected var _special_2_keyup_action:Function  = function() {};
		
		protected var _special_3_keydown_action:Function = function () {};
		protected var _special_3_keyup_action:Function  = function() {};
		
		protected var _special_4_keydown_action:Function = function () {};
		protected var _special_4_keyup_action:Function  = function() {};
		
		
		public function ICharacter(){ addEventListener("addedToStage", addKeyListeners); };
		
		protected function addKeyListeners(evt:Event):void{
			this.stage.addEventListener("keyDown", checkKeysDown);
			this.stage.addEventListener("keyUp", checkKeysUp);
		}
		
		protected function checkKeysDown(evt:KeyboardEvent):void{
			//trace(evt.keyCode);
			switch (evt.keyCode){
				case _leftkey:
				scaleX = 1;
				if (currentLabel != "walking") gotoAndStop("walking");
				_left_keydown_action();
				_leftIsDown = true;
				break;
				
				case _rightkey:
				scaleX = -1;
				if (currentLabel != "walking") gotoAndStop("walking");
				_right_keydown_action();
				_rightIsDown = true;
				break;
				
				case _upkey:
					if (!_falling){
						if (currentLabel != "jump") gotoAndStop("jump");
						_myJump = -_jumpheight;
						_up_keydown_action();
						_falling = _upIsDown = true;
					}
				break;
				
				case _downkey:
					_down_keydown_action();
					_downIsDown = true;
				break;
				
				case _special_1:
				if (!_special1IsDown) _special_1_keydown_action();
				_special1IsDown = true;
				break;
			}
		}
		
		protected function checkKeysUp(evt:KeyboardEvent):void{
			
			switch (evt.keyCode){
				case _leftkey:
				_left_keyup_action();
				_leftIsDown = false;
				break;
				
				case _rightkey:
				_right_keyup_action();
				_rightIsDown = false;
				break;
				
				case _upkey:
				_up_keyup_action();
				_upIsDown = false;
				break;
				
				case _downkey:
				_down_keyup_action();
				_downIsDown = false;
				break;
				
				case _special_1:
				_special_1_keyup_action();
				_special1IsDown = false;
				break;
			}
		}
											
		override public function moveRight(evt:Event):void{
			x += _speed;
			if (!_falling && !_boundaries.hitTestPoint(x, y+(height/2), true) && !_boundaries.hitTestPoint(x-(width/2), y+(height/2), true) && !_boundaries.hitTestPoint(x-(width/2), y-(height/2), true) ){
				_myJump = _fallspeed;
				addEventListener("enterFrame", moveDown);				
			}
			checkBounds();
		}
		
		override public function moveLeft(evt:Event):void{
			x -= _speed;
			
			if (!_falling && !_boundaries.hitTestPoint(x, y+(height/2), true) && !_boundaries.hitTestPoint(x-(width/2), y+(height/2), true) && !_boundaries.hitTestPoint(x-(width/2), y-(height/2), true) ){
				_myJump = _fallspeed;
				addEventListener("enterFrame", moveDown);
				gotoAndStop("fall");
			}
			checkBounds();
		}
		
		
		protected function moveDown(evt:Event):void{
			_falling = true;
	  		if (!_boundaries.hitTestPoint(x, y+(height/2), true) && !_boundaries.hitTestPoint(x-(width/3), y+(height/2), true) &&  !_boundaries.hitTestPoint(x+(width/3), y+(height/2), true)){
		  		y += _myJump;
		  		_myJump += _fallspeed;
		  		checkBounds();
	  		}
	  		else {
		  		_falling = false;
				for (var i:int = 0; i < height/2 - _fallspeed; i++){
					if (_boundaries.hitTestPoint(x, y + i, true)){
						y -=  ((height/2) - i);
						// break;
					}
				}
				
				if (_upIsDown && !_falling){
					gotoAndStop("jump");
					_myJump = -_jumpheight;
					_up_keydown_action();
					_falling = _upIsDown = true;
				}
				
				if ((_leftIsDown || _rightIsDown) && currentLabel != "walking")  gotoAndStop("walking");
				else gotoAndStop("standing");
				removeEventListener("enterFrame", moveDown);
			}
		}
				
		protected function moveUp(evt:Event):void{
			if (_boundaries && !_boundaries.hitTestPoint(x, y-(height/2), true) && !_boundaries.hitTestPoint(x-(width/3), y-(height/2), true) && !_boundaries.hitTestPoint(x+(width/3), y-(height/2), true)){
	   			y += _myJump;
	   			_myJump += _fallspeed;
			}
	   		else {
		   		_myJump = 0;
	   		}
			
			if (_myJump>=0) {
				removeEventListener("enterFrame", moveUp);
				addEventListener("enterFrame", moveDown);
				gotoAndStop("fall");
	   		}
	   		checkBounds();
		}
								
		protected function checkBounds():void{
			  var y1;
			  var x1;
			  if (y > root.stage.stageHeight){
				  y = 0;
				  if (_boundaries.hitTestPoint(x, y, true) || _boundaries.hitTestPoint(x, y+(height/2), true)){
					y = root.stage.stageHeight;
				  }
			  }
					
			  if (y < 0){
				  
				  y = root.stage.stageHeight;
				  if (_boundaries.hitTestPoint(x, y, true) || _boundaries.hitTestPoint(x, y-(height/2), true)){
					y = 0;
					addEventListener("enterFrame", moveDown);
					gotoAndStop("fall");
				  }
			  }
			  if (x < 0) {
				  x1 = x;
				  x = root.stage.stageWidth;
				  if (_boundaries.hitTestPoint(x, y, true) || _boundaries.hitTestPoint(x-(width/2), y, true)){
					x = 0;
				  }
			  }
			  if (x > root.stage.stageWidth) {
				  x1 = x;
				  x = 0;
				  if (_boundaries.hitTestPoint(x, y, true) || _boundaries.hitTestPoint(x+(width/2), y, true)){
					x = root.stage.stageWidth;
				  }
			  }
		}		
		
		//Getters and Setters
		public function get fallspeed():int{
			return _fallspeed;
		}
		
		public function set fallspeed(val:int){
			_fallspeed = fallspeed;
		}
			
		
		public function get jumpheight():int{
			return _jumpheight;
		}
		
		public function set jumpheight(val:int):void{
			_jumpheight = val;
		}		
		
	}
	
}